package com.thkj.util;

import java.io.IOException;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.thkj.entity.TblSecurityAdmin;
import com.thkj.service.TblSecurityAdminService;

import cn.hutool.core.util.StrUtil;
import dp.R;
import dp.util.CookieUtil;
import dp.util.DateUtil;
import dp.util.SpringUtil;

/**
 * 公共类
 *
 * @author Administrator
 */
public class RmUtil {
    protected static final Logger logger = LoggerFactory.getLogger(RmUtil.class);

    private static final String USERINFO_REQUEST_NAME = "rmsso";
    private static final String JWT_TOKEN = "JWT_TOKEN_mg";

    /**
     * 创建JWT
     */
    public static String createJWT(RmLoginUserInfo loginUserInfo, String jwt_secret) {
        String jwt_token = null;
        try {
            jwt_token = JWT.create().withClaim("userId", loginUserInfo.getUserId())
                    .withClaim("userCode", StringUtils.defaultString(loginUserInfo.getUserCode()))
                    .withClaim("userName", StringUtils.defaultString(loginUserInfo.getUserName()))
                    .withClaim("loginTime", loginUserInfo.getLoginTime().getTime() + "")
                    .withClaim("roleId", loginUserInfo.getRoleId())
                    .withClaim("headUrl", loginUserInfo.getHeadUrl())
                    .sign(Algorithm.HMAC256(jwt_secret));
        } catch (Exception e) {
            logger.error("createJWT Error", e);
        }
        return jwt_token;
    }

    /**
     * 向客户端cookie设置当前用户信息
     */
    public static void setLoginUserInfoAtCookie(HttpServletResponse response, TblSecurityAdmin rmPerson) {
        if (rmPerson == null) {
            throw new IllegalArgumentException("不能为空");
        }

        RmLoginUserInfo loginUserInfo = new RmLoginUserInfo();
        loginUserInfo.setUserId(rmPerson.getId());
        loginUserInfo.setHeadUrl(rmPerson.getImageUrl());
        loginUserInfo.setUserCode(rmPerson.getLoginName());
        loginUserInfo.setRoleId(rmPerson.getRoleId());
        loginUserInfo.setUserName(StrUtil.isBlank(rmPerson.getRealName()) ? rmPerson.getLoginName() : rmPerson.getRealName());
        loginUserInfo.setLoginTime(DateUtil.getNowAsTimestamp());
        // 从配置文件获取秘钥
        String jwtSecret = PropertiesUtils.getProperty("RM_JWT_SECRET");
        String jwt_token = RmUtil.createJWT(loginUserInfo, jwtSecret);
        CookieUtil.setCookie(response, JWT_TOKEN, jwt_token, null, -1, true);
    }

    /**
     * 退出删除cookie
     */
    public static void clearLoginUserInfoFromCookie(HttpServletResponse response) {
        CookieUtil.deleteCookie(response, JWT_TOKEN);
    }

    /**
     * 从cookie中取当前登录的用户信息
     *
     * @return
     */
    public static RmLoginUserInfo getLoginUserFromCookie(HttpServletRequest request) {
        String jwt_token = CookieUtil.getCookie(request, JWT_TOKEN);
        if (StringUtils.isBlank(jwt_token)) {
            return null;
        }
        // 从配置文件获取秘钥
        String jwtSecret = PropertiesUtils.getProperty("RM_JWT_SECRET");
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(jwtSecret)).build();
            DecodedJWT jwt = verifier.verify(jwt_token);

            RmLoginUserInfo userInfo = new RmLoginUserInfo();
            userInfo.setUserId(jwt.getClaim("userId").asString());
            userInfo.setUserCode(jwt.getClaim("userCode").asString());
            userInfo.setRoleId(jwt.getClaim("roleId").asInt());
            userInfo.setUserName(jwt.getClaim("userName").asString());
            userInfo.setHeadUrl(jwt.getClaim("headUrl").asString());
            userInfo.setLoginTime(new Timestamp(Long.valueOf(jwt.getClaim("loginTime").asString())));
            return userInfo;
        } catch (Exception e) {
            logger.error("getLoginUserFromCookie Error", e);
            return null;
        }
    }

    /**
     * 把登录用户信息存入request中方便后续取用
     *
     * @param loginUserInfo
     */
    public static void setLoginUserInfo(HttpServletRequest request, RmLoginUserInfo loginUserInfo) {
        request.setAttribute(USERINFO_REQUEST_NAME, loginUserInfo);
    }

    /**
     * 从request中取当前登录的用户信息，避免多次从cookie获取
     *
     * @return
     */
    public static RmLoginUserInfo getLoginUser(HttpServletRequest request) {
        return (RmLoginUserInfo) request.getAttribute(USERINFO_REQUEST_NAME);
    }

    /**
     * 根据用户id取用户信息
     *
     * @param personuuid
     * @return
     */
    public static TblSecurityAdmin getRmPerson(String personuuid) {
        TblSecurityAdminService rmPersonService = (TblSecurityAdminService) SpringUtil.getBean(TblSecurityAdminService.class);
        return rmPersonService.getTblSecurityAdminById(personuuid);
    }

    /**
     * 根据菜单将完整tree过滤
     *
     * @param list
     */
    public static void getAvailableTree(List<Map> list, List<String> menuList) {
        for (int i = 0; i < list.size(); i++) {
            Map m = list.get(i);
            if (m.get("children") != null) {
                List<Map> children = (List<Map>) m.get("children");
                getAvailableTree(children, menuList);
                if (children.size() == 0) {
                    list.remove(m);
                    i--;
                }
            } else {
                boolean isRemove = true;
                for (String id : menuList) {
                    if (StringUtils.equals(id, m.get("id").toString())) {
                        isRemove = false;
                        break;
                    }
                }
                if (isRemove) {
                    list.remove(m);
                    i--;
                }
            }
        }
    }

    /**
     * 是否系统管理员
     *
     * @return
     */
    public static boolean isAdmin(RmLoginUserInfo loginUser) {
        return loginUser.getUserCode().equals(PropertiesUtils.getProperty("RM_SYSTEM_USER"));
    }

    public static void noLogin(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String xReq = request.getHeader("x-requested-with");
        if (StringUtils.isNotBlank(xReq) && "XMLHttpRequest".equalsIgnoreCase(xReq)) {
            response.setCharacterEncoding("UTF-8");
            response.getWriter().println(JSON.toJSONString(R.failure("登录超时,请重新登录!")));
        } else {
            response.sendRedirect(request.getContextPath() + "/");
        }
    }

    public static void noAuthorize(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String xReq = request.getHeader("x-requested-with");
        if (StringUtils.isNotBlank(xReq) && "XMLHttpRequest".equalsIgnoreCase(xReq)) {
            response.setContentType("application/json;charset=utf-8");
            response.getWriter().println(JSON.toJSONString(R.failure("权限不足!")));
        } else {
            response.setContentType("text/html;charset=utf-8");
            response.sendRedirect(request.getContextPath() + "/user/noAuthorize");
        }
    }
}
